package com.superbytecode.cloud.web.exception;

import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.fastjson.JSON;
import com.superbytecode.cloud.common.result.ResultWrapper;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import static com.superbytecode.cloud.common.exception.ErrorCodeEnum.SENTINEL_BLOCKED;
import static org.springframework.http.HttpStatus.TOO_MANY_REQUESTS;

/**
 * All rights Reserved, Designed By www.super-master.com
 *
 * @ProjectName: beacon-cloud
 * @Package: com.superbytecode.cloud.web.exception
 * @ClassName: SentinelBlockExceptionHandler
 * @Description: [Sentinel自定义异常处理]
 * <p> Sentinel
 * 默认情况下，发生限流、降级、授权拦截时，都会抛出异常到调用方，
 * 如果要自定义异常时的返回结果，需要实现BlockExceptionHandler接口：
 * </p>
 * @Author: [Lance Ting]
 * @Date: 2024/10/21 18:39
 * @Version: V1.0
 * @Copyright: 2024 www.super-master.cn Inc. All rights reserved.
 * TODO: 注意,本文件Lance Ting所作,如果转载或使用请标明具体出处!
 **/
@Component
public class SentinelBlockExceptionHandler implements BlockExceptionHandler {

    /**
     * 服务降级异常处理
     * <p>
     * BlockException包含很多个子类，分别对应不同的场景：
     * FlowException -->        限流异常
     * ParamFlowException -->   热点参数限流的异常
     * DegradeException -->     降级异常
     * AuthorityException -->   授权规则异常
     * SystemBlockException --> 系统规则异常
     * </p>
     *
     * @param request  请求
     * @param response 响应
     * @param ex       异常信息
     * @throws Exception 异常
     */
    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, BlockException ex) throws Exception {
        ResultWrapper<Object> failureMgs = ResultWrapper.failure(SENTINEL_BLOCKED);
        response.setStatus(TOO_MANY_REQUESTS.value());
        response.setHeader("content-type", "application/json;charset=UTF-8");
        response.getWriter().write(JSON.toJSONString(failureMgs));
    }
}